/*    file: main.cpp
 *    desc:
 * 
 * created: 2016-04-06
 *  author: chuanjiang.zh@qq.com
 * company: 
 */

#include <stdio.h>
#include <iostream>

#include "BasicType.h"
#include "SharedPtr.h"
#include "TFileUtil.h"
#include "TByteBuffer.h"
#include "BasicMacro.h"
#include "TStringUtil.h"
#include <assert.h>
#include <errno.h>
#include "FfmpegMediaReader.h"
#include "LoopReader.h"
#include "LitePlayer.h"
#include "DateTime.h"
#include "Path.h"
#include <memory>
#include "TimePoint.h"


typedef std::shared_ptr< av::LitePlayer >		LitePlayerPtr;
typedef std::shared_ptr< av::InputPlayer >		InputPlayerPtr;


class Application 
{
public:
	Application()
	{
		av::LitePlayerFactory::startup();
	}

	~Application()
	{
		av::LitePlayerFactory::cleanup();
	}

};


int main(int argc, char** argv)
{
	std::string filename = "rtsp://admin:sjld16301@192.168.3.65/";
	//rtsp://192.168.1.230/main
	filename = "f:\\media\\love.mp4";
	// rtsp://192.168.2.105/demo

	if (argc > 1)
	{
		filename = argv[1];
	}

	Application app;

	InputPlayerPtr  player(av::LitePlayerFactory::createInputPlayer(NULL), av::LitePlayerFactory::destroy);
	
	LoopReader reader;
	int rc = reader.open(filename.c_str());
	if (rc != 0)
	{
		return rc;
	}

	MFormat fmt;
	memset(&fmt, 0, sizeof(fmt));
	fmt.width = reader.m_width;
	fmt.height = reader.m_height;
	fmt.framerate = reader.m_fps;
	fmt.codec = reader.m_codec;
	fmt.vProp = (uint8_t*)(reader.m_prop.c_str());
	fmt.vPropSize = reader.m_prop.size();
	fmt.clockRate = AV_TIME_BASE;

	fmt.channels = reader.m_channels;
	fmt.sampleRate = reader.m_sampleRate;
	fmt.audioCodec = reader.m_acodec;
	fmt.config = (uint8_t*)(reader.m_config.c_str());
	fmt.configSize = reader.m_config.size();
	fmt.audioRate = AV_TIME_BASE;

	rc = player->open(fmt);
	player->play();

	comn::TimePoint timePoint;

	int count = 50000/2;
	while (count > 0)
	{
		count --;

		AVPacket pkt;
		av_init_packet(&pkt);

		rc = reader.read(pkt);
		if (rc != 0)
		{
			break;
		}

		MPacket mpkt;
		memset(&mpkt, 0, sizeof(mpkt));
		mpkt.data = pkt.data;
		mpkt.size = pkt.size;
		mpkt.pts = pkt.pts;
		mpkt.flags = pkt.flags;
		mpkt.duration = pkt.duration;
		mpkt.type = pkt.stream_index;
		
		player->write(mpkt);

		if (!reader.isLive() && (pkt.stream_index == 0))
		{ 
			comn::TimePoint curPoint(av_gettime(), pkt.pts);
			if (!timePoint.isSet())
			{
				timePoint = curPoint;
			}
			
			int64_t clockDelta = curPoint.m_clock - timePoint.m_clock;
			int64_t ptsDelta = curPoint.m_pts - timePoint.m_pts;
			//int offset = (int)(ptsDelta - clockDelta);
			int64_t offset = curPoint.getOffset(timePoint);
			//printf("origin clock: %lld, pts: %lld, cur clock: %lld, pts: %lld, clockDelta: %lld, ptsDelta: %lld, offset: %d\n",
			//	timePoint.m_clock, timePoint.m_pts, curPoint.m_clock, curPoint.m_pts,
			//	clockDelta, ptsDelta, (int)offset);

			if (offset > 1000 * 20)
			{
				av_usleep(offset);
			}
		}

		av_packet_unref(&pkt);
	}

	player->stop();

	
	return 0;
}




